package amazon

import (
	"encoding/json"
	"fmt"
	"gitee.com/wengo/go-mamba"
	"github.com/PuerkitoBio/goquery"
	uuid "github.com/satori/go.uuid"
	"github.com/tidwall/gjson"
	"regexp"
	"strings"
	"time"
)

type AddressSuggestions struct {
	Recipient     string
	Phone         string
	AddressLine1  string `json:"ADDRESS_LINE_1"`
	AddressLine2  string `json:"ADDRESS_LINE_2"`
	PostalCode    string `json:"POSTAL_CODE"`
	City          string `json:"CITY"`
	StateOrRegion string `json:"STATE_OR_REGION"`
	CountryCode   string `json:"COUNTRY_CODE"`
}

// 提取CsrfToken数据
//
// document: 当前返回的Response
func (a *Amazon) ExtractCsrfToken(document *goquery.Document) (token string, err error) {
	token, exists := document.Find("#glowValidationToken").Attr("value")
	if exists {
		return token, nil
	} else {
		return "", fmt.Errorf("无法抓取首页的csrf token")
	}
}

// 选择地址
//
//csrf: csrf token
func (a *Amazon) AddressSelection(csrf string) (resp *mamba.Response, document *goquery.Document, err error) {
	headers := map[string]interface{}{
		"anti-csrftoken-a2z": csrf,
		"referer":            a.client.BaseURL,
	}

	query := map[string]string{
		"deviceType":   "desktop",
		"pageType":     "Gateway",
		"storeContext": "NoStoreName",
		"actionSource": "desktop-modal",
	}

	resp, document, err = a.Ajax(`/portal-migration/hz/glow/get-rendered-address-selections`, GET, headers, query, nil)
	//resp, document, err = a.request(GET, "/gp/glow/get-address-selections.html", headers, nil, query) # older链接
	//resp, document, err = a.request(GET, "/portal-migration/hz/glow/get-rendered-address-selections", headers, nil, query)

	return
	//return a.amz.request(GET, "/gp/glow/get-address-selections.html", headers, nil, query), nil, nil
}

// 获取修改地址的表单
//
// document: 首页的document

func (a *Amazon) ExtractAddressForm(document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
	//提取首页token
	token, err := a.ExtractCsrfToken(document)
	if err != nil {
		return nil, nil, err
	}

	//提取地址token
	return a.AddressSelection(token)
}

// ChangeAddress 修改地址
//
// document: 首页的document
func (a *Amazon) ChangeAddress(document *goquery.Document, zipCode string) (resp *mamba.Response, err error) {
	//提取首页token
	token, err := a.ExtractCsrfToken(document)
	if err != nil {
		return nil, err
	}

	//提取地址token
	resp, document, err = a.AddressSelection(token)

	if err != nil {
		return
	} else {
		html, _ := document.Html()
		reg, _ := regexp.Compile(`CSRF_TOKEN\s*:\s*"([^"]+)"`)
		matcher := reg.FindStringSubmatch(html)

		formData := map[string]string{
			"locationType": "LOCATION_INPUT",
			"zipCode":      zipCode,
			"storeContext": "generic",
			"deviceType":   "web",
			"pageType":     "Gateway",
			"actionSource": "glow",
			"almBrandId":   "undefined",
		}

		if len(matcher) > 0 {
			header := map[string]interface{}{
				"anti-csrftoken-a2z": matcher[1],
				//"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
				//"referer":            a.client.BaseURL,
				"origin": a.Base.client.BaseURL,
				//"content-length":"135",
				//"Accept":			"text/html,*/*",
			}
			resp, _, err = a.Ajax(AddressChange, POST, header, nil, formData)
			//resp, _, err = a.Submit(AddressChange, POST, header, nil, formData)
			//resp, _, err = a.request(POST,
			//	AddressChange,
			//	map[string]string{
			//		"anti-csrftoken-a2z": matcher[1],
			//		"X-Requested-With":   "XMLHttpRequest",
			//		"referer":            a.client.BaseURL,
			//	},
			//	formData,
			//	nil)

		} else {
			return resp, fmt.Errorf("无法修改地址")
		}
	}

	return
}

// 判断是否地址页面
//
// document: 添加地址页面的document
func (a *Amazon) IsShippingAddressPage(document *goquery.Document) bool {
	return document.Find("#address-ui-address-form").Size() > 0
}

// 添加用户地址
//
// document: 添加地址页面的document
func (a *Amazon) AddAddress(address AddressSuggestions, document *goquery.Document) (resp *mamba.Response, newDocument *goquery.Document, err error) {
	action, method, addressFormData, err := a.ExtractFormData(document, "#address-ui-address-form")
	if err != nil {
		return nil, nil, err
	}

	addressFormData["address-ui-widgets-countryCode"] = "US"
	addressFormData["address-ui-widgets-enterAddressFullName"] = address.Recipient
	addressFormData["address-ui-widgets-enterAddressPhoneNumber"] = address.Phone
	addressFormData["address-ui-widgets-enterAddressLine1"] = address.AddressLine1
	addressFormData["address-ui-widgets-enterAddressLine2"] = ""
	addressFormData["address-ui-widgets-enterAddressCity"] = address.City
	addressFormData["address-ui-widgets-enterAddressStateOrRegion"] = address.StateOrRegion
	addressFormData["address-ui-widgets-enterAddressPostalCode"] = address.PostalCode
	addressFormData["address-ui-widgets-use-as-my-default"] = "true"

	resp, newDocument, err = a.Submit(action, method, nil, nil, addressFormData)

	return
}

func (a *Amazon) AddressSuggestion(code, searchText string) (suggestiongs AddressSuggestions, err error) {
	//number := RandomInt(1, 10000)
	var resp *mamba.Response
	var targetAddress string
	switch code {
	case "uk":
		resp, _, err = a.json(`https://addresssuggest-eu.amazon.com/v1/lookup/places`, map[string]string{"Origin": a.client.BaseURL}, map[string]interface{}{
			"partialAddress": map[string]interface{}{
				"postalCode":  searchText,
				"countryCode": "GB",
			},
		})

		if err != nil {
			return suggestiongs, err
		}

		suggestiongs.AddressLine1 = gjson.Get(resp.String(), "places.0.address.addressline1").String()
		suggestiongs.AddressLine2 = gjson.Get(resp.String(), "places.0.address.addressline2").String()
		suggestiongs.City = gjson.Get(resp.String(), "places.0.address.city").String()
		suggestiongs.CountryCode = gjson.Get(resp.String(), "places.0.address.countryCode").String()
		suggestiongs.PostalCode = gjson.Get(resp.String(), "places.0.address.postalCode").String()

	default:
		resp, _, err = a.json(AddressSuggestion, nil, map[string]interface{}{
			"countryCode":       strings.ToUpper(code),
			"addressSearchText": searchText,
			"additionalContext": map[string]interface{}{
				"INTERACTION_ID": uuid.NewV4(),
			},
		})

		if err != nil {
			return suggestiongs, err
		}

		targetAddress = gjson.Get(resp.String(), "addressSuggestions.0.addressFields").String()
		for _, address := range gjson.Get(resp.String(), "addressSuggestions.#.addressFields").Array() {
			// 这三个是部队的州，买的太多不会能发货到这三个州去
			if address.Get("STATE_OR_REGION").String() != "AE" && address.Get("STATE_OR_REGION").String() != "AP" && address.Get("STATE_OR_REGION").String() != "AA" {
				targetAddress = address.String()
				break
			}
		}

		err = json.Unmarshal([]byte(targetAddress), &suggestiongs)
	}

	//err = json.Unmarshal([]byte(gjson.Get(resp.String(), "addressSuggestions.0.addressFields").String()), &suggestiongs)
	return

}

func (a *Amazon) CheckAddress() bool {
	//headers := map[string]string{
	//	"anti-csrftoken-a2z": csrftoken,
	//	"X-Requested-With":   "XMLHttpRequest",
	//	"referer":            a.client.BaseURL,
	//}
	//
	//_, document, err := a.request(GET, AddressSelections, headers, nil, nil)
	//if err != nil {
	//
	//} else {
	//	html, _ := document.Html()
	//	ioutil.WriteFile("address.html", []byte(html), 0644)
	//	if document.Find("#GLUXAddressList").Length() > 0 {
	//		//if strings.Contains(document.Find("#glow-ingress-line2").Text(), "China") {
	//		//_ = a.ChangeAddress(document)
	//		return true
	//	}
	//}

	_, document, err := a.Navigate("/")
	if err != nil {

	} else {
		//if document.Find("#GLUXAddressList").Length() > 0 {
		if strings.Contains(document.Find("#glow-ingress-line2").Text(), "China") {
			return true
		}
	}

	return false

}

func (a *Amazon) WaitAddressChange(document *goquery.Document) {
	for {
		if a.CheckAddress() {
			time.Sleep(10 * time.Second)
		} else {
			break
		}
	}
}
